package com.ruoyi.face.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.arcsoft.face.FaceInfo;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.face.dto.*;
import com.ruoyi.face.entity.UserInfo;
import com.ruoyi.face.service.FaceEngineService;
import com.ruoyi.face.util.UserRedisCache;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;


@RestController
@Slf4j
@RequestMapping("/face")
public class FaceController extends BaseController {

    @Autowired
    private FaceEngineService faceEngineService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    UserRedisCache userRedisCache;
    @Value("${ruoyi.profile}")
    private String profile;

    //初始化注册人脸，注册到本地内存
    @PostConstruct
    public void initFace() {
        userRedisCache.clear();
        List<SysUser> userList = sysUserService.selectAvatarList(new SysUser());
        for (SysUser user : userList) {
            if (user.getAvatar() != null) {
                String avatarPath = user.getAvatar().replace("/profile", profile);
                try (InputStream inputStream = Files.newInputStream(Paths.get(avatarPath))) {
                    ImageInfo rgbData = ImageFactory.getRGBData(inputStream);
                    List<FaceInfo> faceInfoList = faceEngineService.detectFaces(rgbData);
                    if (CollectionUtil.isNotEmpty(faceInfoList)) {
                        byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfoList.get(0));
                        UserInfo userInfo = new UserInfo(user.getAvatar(), avatarPath, user.getUserName(), feature);
                        userRedisCache.addUser(userInfo);
                    }
                } catch (IOException e) {
                    log.error("读取用户 {} 头像文件失败: {}", user.getNickName(), e.getMessage(), e);
                }
            }
        }
    }

    // HTTP接口方法
    @PostMapping("/init")
    public AjaxResult initFaceEndpoint() {
        initFace(); // 调用初始化方法
        return success("初始化完成");
    }

    /*
    人脸添加
     */
    @PostMapping("/add")
    public AjaxResult faceAdd(@RequestBody FaceAddReqDTO faceAddReqDTO) {
        String avatarPath = faceAddReqDTO.getImgUrl().replaceAll("/profile", profile);
        try (InputStream inputStream = Files.newInputStream(Paths.get(avatarPath))) {
            ImageInfo rgbData = ImageFactory.getRGBData(inputStream);
            List<FaceInfo> faceInfoList = faceEngineService.detectFaces(rgbData);
            if (CollectionUtil.isNotEmpty(faceInfoList)) {
                byte[] feature = faceEngineService.extractFaceFeature(rgbData, faceInfoList.get(0));
                UserInfo userInfo = new UserInfo(faceAddReqDTO.getImgUrl(), avatarPath, faceAddReqDTO.getName(), feature);
                userRedisCache.addUser(userInfo);
            }
        } catch (IOException e) {
            log.error("添加用户 {} 头像文件失败: {}", faceAddReqDTO.getName(), e.getMessage(), e);
        }
        return success();
    }


    @GetMapping("/list")
    public TableDataInfo getFaceList() {
        List<UserInfo> userList = userRedisCache.getUserList();
        List<GetFaceListResDTO> resDTOS = new ArrayList<>();
        for (UserInfo userInfo : userList) {
            GetFaceListResDTO face = new GetFaceListResDTO();
            face.setId(userInfo.getFaceId());
            face.setName(userInfo.getName());
            face.setUrl(userInfo.getUrl());
            resDTOS.add(face);
        }
        return getDataTable(resDTOS);
    }

}
